using System;
using Rhizome.Contract;

namespace Rhizome.Model
{
	public abstract class MessageBase : IMessage
	{
		#region Implementation of IIdentityAccessor

		public object Id { get; set; }

		#endregion

		protected MessageBase()
		{
		}

		protected MessageBase(object id)
		{
			if (id == null) throw new ArgumentNullException("id");
			Id = id;
		}

		public override bool Equals(object obj)
		{
			if (ReferenceEquals(null, obj)) return false;
			if (ReferenceEquals(this, obj)) return true;
			var m = obj as IIdentityAccessor;
			return m != null && Equals(m.Id, Id);
		}

		public override int GetHashCode()
		{
			return Id.GetHashCode();
		}

		public override string ToString()
		{
			return string.Format("Message {0}", Id);
		}
	}

	public abstract class Message<TData> : MessageBase
	{
		protected Message(object id) : base(id)
		{
		}

		protected Message(object id, TData data) : base(id)
		{
			Data = data;
		}

		protected Message()
		{
		}

		public TData Data { get; set; }

		public override string ToString()
		{
			return string.Format("{0}, Data={1}", base.ToString(), Data);
		}
	}

	public sealed class Message : Message<object>
	{
		public Message(object id, object data) : base(id, data)
		{
		}

		public Message()
		{
		}

		public Message(object id) : base(id)
		{
		}
	}
}